/*
 * modsAX Javascript Library
 * modsAX.com 2009 squall
 * modsAX are licensed under a Creative Commons Attribution 3.0 license.
 * http://creativecommons.org/licenses/by/3.0/deed.ko
 * If you don't want to author Link
 * You must register. Join the modsAX license member then you free use modsAX
 * http://www.modsAX.com
 */

jQuery.fn.modsDate = function(arg){
  if(arg == undefined) arg = {}
  var varObj = new modsDate();
  arg.inputID = this.get(0).id;
  varObj.setConfig(arg);
  return this;
};

var modsCalendar = Class.create(modsAX, {
  version       : "modsCalendar V1.0",
  author        : "SQUALL",
  createDate    : "2010.04.26",
  lastModifyDate: "2010.04.29",
  initialize: function($super){
    $super();
    this.today = new Date();
    this.panelStat = 2;
    this.otherClick;
    with(this){
      config.now = new Date();
      config.nowYear = config.now.getFullYear();
      config.nowPYear = config.nowYear;
      config.bef = config.now.add(-1, "m");
      config.aft = config.now.add(1, "m");
      config.weekNames = ["일", "월", "화", "수", "목", "금", "토"];
      config.hcanvas = "calendarHContainer";
      config.canvas = "calendarCanvas";
      config.dayPanel = "calendarPanelday";
      config.monthPanel = "calendarPanelmonth";
      config.yearPanel = "calendarPanelyear";
      config.nowDateCss = "nowDate";
      config.toDateCss = "toDate";
      config.nowMonthCss = "nowMonth";
      config.nowYearCss = "nowYear";
      config.dim = {width:150, height:133};
      config.easing = "expoInOut";
      config.duration = 300;
    }
  },
  init: function(){
    this.container = jQuery("<div class=\""+this.config.canvas+"\" id=\""+this.config.calendarStage+"_container\"></div>");
    this.hContainer = jQuery("<div class=\""+this.config.hcanvas+"\" id=\""+this.config.calendarStage+"_hcontainer\"></div>");
    this.hContainer.bind("click", this.onClick.bind(this));
    this.container.css(this.config.dim);
    this.hContainer.css({width:this.config.dim.width*3, height:this.config.dim.height, left:-this.config.dim.width*2, top:0});
    this.container.append(this.hContainer);
    jQuery("#"+this.config.calendarStage).append(this.container);
    this.initMonth();
  },
  initMonth: function(){
    with(this){
      hContainer.find("."+config.dayPanel).remove();
      var b = config.bef, n = config.now, a = config.aft;
      hContainer.append("<div class=\""+config.dayPanel+"\" style=\"top:-"+config.dim.height+"px;\" id=\""+config.calendarStage+"_"+b.say().left(7)+"\">"+getPage(b)+"</div>");
      hContainer.append("<div class=\""+config.dayPanel+"\" id=\""+config.calendarStage+"_"+n.say().left(7)+"\">"+getPage(n)+"</div>");
      hContainer.append("<div class=\""+config.dayPanel+"\" style=\"top:"+config.dim.height+"px;\" id=\""+config.calendarStage+"_"+a.say().left(7)+"\">"+getPage(a)+"</div>");
      jQuery("."+config.dayPanel).css({left:config.dim.width*2, width:config.dim.width, height:config.dim.height});
      if(this.panelStat == 2) if(config.onDisplay) config.onDisplay(n.say().left(7).replace("-", "년 ")+"월");
      this.dayActive(true);
    }
    this.active = true;
  },
  getPage: function(d){
    var calendarStage = this.config.calendarStage;
    var po = [];

    var mfd = new Date(d.getFullYear(), d.getMonth(), 1);
    var mfdw = mfd.getDay();
    var psd = mfd.add(-mfdw);

    var nd = psd;
    var z = 0;
    var tdcs = ["prevmonth", "", "nextmonth"], tdcsi = 0;
    var nMonth = this.today.getMonth();
    var nDate = this.today.getDate();
    var sm = nd.getMonth();
    var ys = (nd.getFullYear() == this.today.getFullYear()) ? 1 : 0;
    po.push("<table cellspacing=\"0\" cellpadding=\"0\">");
    var i = 0; while(i < 6){
      if(i == 0){
      po.push( "<thead>" );
      po.push( "<tr>" );
      var k = 0; while(k < 7){
          po.push( "<td id=\""+calendarStage+"_h\">" + this.config.weekNames[k] + "</td>" );
      k++;}
      po.push( "</tr>" );
      po.push( "</thead>" );
      po.push( "<tbody>" );
      }
      po.push( "<tr>" );
      var k = 0; while(k < 7){
        var nd = psd.add(z);
          var dd = nd.say(6);
          if(dd == 1){tdcsi++;sm++;}
          var addCss = ""; if(sm == nMonth && dd == nDate && ys == 1) addCss = " "+this.config.toDateCss;
          po.push( "<td><a href=\"#MES_"+tdcsi+"_"+nd.say()+"\" class=\""+tdcs[tdcsi] + addCss +"\" id=\""+calendarStage+"_"+tdcsi+"_"+nd.say()+"\">" + dd + "</a></td>" );
      z++;k++;}
      po.push( "</tr>" );
    i++;}
    po.push("</tbody>");
    po.push("</table>");
    return po.join('');
  },
  getMonthPage: function(){
    var calendarStage = this.config.calendarStage;
    var dh = Math.floor(this.config.dim.height/4);
    var po = [];
    po.push("<table cellspacing=\"0\" cellpadding=\"0\">");
    po.push( "<tbody>" );
    var z = 1;
    var i = 0; while(i < 4){
      po.push( "<tr>" );
      var k = 0; while(k < 3){
        po.push( "<td style=\"height:"+dh+"px\"><a href=\"#MES_"+z+"\" id=\""+calendarStage+"_m_"+z+"\" style=\"height:"+(dh-4)+"px;line-height:"+(dh-4)+"px;\">" + z + "월</a></td>" );
      z++;k++;}
      po.push( "</tr>" );
    i++;}
    po.push("</tbody>");
    po.push("</table>");
    return po.join('');
  },
  getYearPage: function(){
    var calendarStage = this.config.calendarStage;
    var dh = Math.floor(this.config.dim.height/4);
    var n = this.config.nowPYear-4;
    var po = [];
    po.push("<table cellspacing=\"0\" cellpadding=\"0\">");
    po.push( "<tbody>" );
    var z = n;
    var i = 0; while(i < 4){
      po.push( "<tr>" );
      var k = 0; while(k < 3){
        po.push( "<td style=\"height:"+dh+"px\"><a href=\"#MES_"+z+"\" id=\""+calendarStage+"_y_"+z+"\" style=\"height:"+(dh-4)+"px;line-height:"+(dh-4)+"px;\">" + z + "년</a></td>" );
        z++;
      k++;}
      po.push( "</tr>" );
    i++;}
    po.push("</tbody>");
    po.push("</table>");
    return po.join('');
  },
  setDate: function(d){
    if(this.panelStat != 2){
      this.gotoDay();
      return;
    }
    if(Object.isString(d)){
      this.config.now = d.date();
    }else{
      this.config.now = d;
    }
    this.config.bef = this.config.now.add(-1, "m");
    this.config.aft = this.config.now.add(1, "m");
    this.config.nowYear = this.config.now.getFullYear();
    this.config.nowPYear = this.config.nowYear;
    this.initMonth();
  },
  dayActive: function(act){
    if(act)
    jQuery("#"+this.config.calendarStage+"_1_"+this.config.now.say()).addClass(this.config.nowDateCss);
    else
    jQuery("#"+this.config.calendarStage+"_1_"+this.config.now.say()).removeClass(this.config.nowDateCss);
  },
  monthActive: function(act){
    if(act)
    jQuery("#"+this.config.calendarStage+"_m_"+(this.config.now.getMonth()+1)).addClass(this.config.nowMonthCss);
    else
    jQuery("#"+this.config.calendarStage+"_m_"+(this.config.now.getMonth()+1)).removeClass(this.config.nowMonthCss);
  },
  yearActive: function(act){
    if(act)
    jQuery("#"+this.config.calendarStage+"_y_"+this.config.nowYear).addClass(this.config.nowYearCss);
    else
    jQuery("#"+this.config.calendarStage+"_y_"+this.config.nowYear).removeClass(this.config.nowYearCss);
  },
  moveDay: function(add){
    if(this.panelStat != 2){
      this.gotoDay();
      return;
    }
    if(!this.active) return;
    this.dayActive(false);
    var newDate = this.config.now.add(add, "d");
    if(this.config.now.say().left(7) != newDate.say().left(7)){
      if(add > 0){
        this.moveMonth(1, newDate);
      }else{
        this.moveMonth(-1, newDate);
      }
    }else{
      this.config.now = newDate;
    }
    this.dayActive(true);
  },
  gotoDay: function(){
    this.monthActive(false);
    if(this.panelStat == 2) return;
    this.config.nowYear = this.config.now.getFullYear();
    this.config.nowPYear = this.config.nowYear;
    var dw = this.config.dim.width*2;
    var oncomplete = this.gotoDayEnd.bind(this);
    this.hContainer.animate({left:-dw+"px"}, {duration :this.config.duration, easing:this.config.easing, complete: function(){
      oncomplete();
    }});
  },
  gotoDayEnd: function(){
    this.panelStat = 2;
    this.config.nowYear = this.config.now.getFullYear();
    this.config.nowPYear = this.config.nowYear;
    if(this.config.onDisplay) this.config.onDisplay(this.config.now.say().left(7).replace("-", "년 ")+"월");
  },
  moveMonth: function(direction, setDay){
    if(this.panelStat == 1){
      this.monthActive(false);
      this.config.now = this.config.now.add(direction, "m");
      this.config.bef = this.config.now.add(-1, "m");
      this.config.aft = this.config.now.add(1, "m");
      this.config.nowYear = this.config.now.getFullYear();
      this.config.nowPYear = this.config.nowYear;
      this.initMonth();
      this.monthActive(true);
      if(this.config.onDisplay) this.config.onDisplay(this.config.nowYear+"년");
    }
    if(this.panelStat == 0){
      this.gotoDay();
    }
    if(this.panelStat != 2) return;
    if(this.active){
      this.active = false;
      var oncomplete = this.moveMonthEnd.bind(this);
      var calendarStage = this.config.calendarStage;
      var dh = this.config.dim.height;
      var b = this.config.bef, n = this.config.now, a = this.config.aft;
      if(direction == 1){
        jQuery( "#"+calendarStage+"_"+n.say().left(7) ).animate({top:"-="+dh+"px"}, {duration :this.config.duration, easing:this.config.easing});
        jQuery( "#"+calendarStage+"_"+a.say().left(7) ).animate({top:"-="+dh+"px"}, {duration :this.config.duration, easing:this.config.easing, complete: function(){
          oncomplete(direction, setDay);
        }});
      }
      if(direction == -1){
        jQuery( "#"+calendarStage+"_"+n.say().left(7) ).animate({top:"+="+dh+"px"}, {duration :this.config.duration, easing:this.config.easing});
        jQuery( "#"+calendarStage+"_"+b.say().left(7) ).animate({top:"+="+dh+"px"}, {duration :this.config.duration, easing:this.config.easing, complete: function(){
          oncomplete(direction, setDay);
        }});
      }
    }
  },
  moveMonthEnd: function(direction, setDay){
    this.dayActive(false);
    var b = this.config.bef, n = this.config.now, a = this.config.aft;
    var calendarStage = this.config.calendarStage;
    var newDate = n.add(direction, "m");

    this.config.now = setDay || new Date(newDate.getFullYear(), newDate.getMonth(), 1);
    this.config.bef = this.config.now.add(-1, "m");
    this.config.aft = this.config.now.add(1, "m");

    this.config.nowYear = this.config.now.getFullYear();
    this.config.nowPYear = this.config.nowYear;

    if(direction == 1){
      jQuery("#"+calendarStage+"_"+b.say().left(7)).remove();
      this.hContainer.append("<div class=\""+this.config.dayPanel+"\" "+
      "style=\"left:"+this.config.dim.width*2+"px;top:"+this.config.dim.height+"px;width:"+this.config.dim.width+"px;height:"+this.config.dim.height+"px\" "+
      "id=\""+calendarStage+"_"+this.config.aft.say().left(7)+"\">"+this.getPage(this.config.aft)+"</div>");
    }else{
      jQuery("#"+calendarStage+"_"+a.say().left(7)).remove();
      this.hContainer.append("<div class=\""+this.config.dayPanel+"\" "+
      "style=\"left:"+this.config.dim.width*2+"px;top:-"+this.config.dim.height+"px;width:"+this.config.dim.width+"px;height:"+this.config.dim.height+"px\" "+
      "id=\""+calendarStage+"_"+this.config.bef.say().left(7)+"\">"+this.getPage(this.config.bef)+"</div>");
    }
    if(this.config.onDisplay) this.config.onDisplay(this.config.now.say().left(7).replace("-", "년 ")+"월");
    this.active = true;

    this.dayActive(true);
  },
  gotoMonth: function(){
    if(this.panelStat == 1) return;
    var dw = this.config.dim.width;
    var oncomplete = this.gotoMonthEnd.bind(this);
    if($M(this.config.calendarStage+"_month")){
       //jQuery("#"+this.config.calendarStage+"_month").html(this.getMonthPage());
    }else{
      this.hContainer.append("<div class=\""+this.config.monthPanel+"\" "+
      " style=\"top:0px;left:"+this.config.dim.width+"px;width:"+this.config.dim.width+"px;height:"+this.config.dim.height+"px;\" id=\""+this.config.calendarStage+"_month\">"+this.getMonthPage()+"</div>");
    }
    this.hContainer.animate({left:-dw+"px"}, {duration :this.config.duration, easing:this.config.easing, complete: function(){
      oncomplete();
    }});
  },
  gotoMonthEnd: function(){
    this.panelStat = 1;
    this.config.nowPYear = this.config.nowYear;
    if(this.config.onDisplay) this.config.onDisplay(this.config.nowYear+"년");
    this.monthActive(true);
  },
  moveYear: function(direction){
    if(this.panelStat == 0){
      this.yearActive(false);
      this.config.nowYear += direction;

      this.config.now = new Date(this.config.nowYear, this.config.now.getMonth(), 1);
      this.config.bef = this.config.now.add(-1, "m");
      this.config.aft = this.config.now.add(1, "m");

      if(this.config.nowYear < this.config.nowPYear-4 || this.config.nowYear > this.config.nowPYear+7){
        if(direction > 0) this.config.nowPYear += 12;
        else this.config.nowPYear -= 12;
        jQuery("#"+this.config.calendarStage+"_year").html(this.getYearPage());
      }
      //this.config.nowPYear = this.config.nowYear;

      this.initMonth();
      this.yearActive(true);
    }
    if(this.panelStat == 1){
      this.config.nowYear += direction;
      this.config.nowPYear = this.config.nowYear;
      if(this.config.onDisplay) this.config.onDisplay(this.config.nowYear+"년");
    }
    if(this.panelStat == 2){
      this.gotoMonth();
    }
  },
  gotoYear: function(){
    if(this.panelStat == 0) return;
    var dw = 0;
    var oncomplete = this.gotoYearEnd.bind(this);
    if($M(this.config.calendarStage+"_year")){
      jQuery("#"+this.config.calendarStage+"_year").html(this.getYearPage());
    }else{
      this.hContainer.append("<div class=\""+this.config.yearPanel+"\" "+
      " style=\"top:0px;left:"+dw+"px;width:"+this.config.dim.width+"px;height:"+this.config.dim.height+"px;\" id=\""+this.config.calendarStage+"_year\">"+this.getYearPage()+"</div>");
    }
    this.hContainer.animate({left:-dw+"px"}, {duration :this.config.duration, easing:this.config.easing, complete: function(){
      oncomplete();
    }});
  },
  gotoYearEnd: function(noselect){
    this.panelStat = 0;
    var sy = this.config.nowPYear - 4;
    var ey = this.config.nowPYear + 7;
    if(this.config.onDisplay) this.config.onDisplay(sy+" ~ "+ey+"년");
    this.yearActive(true);
  },
  movePage: function(direction){
    if(this.panelStat == 0){
      this.config.nowPYear += parseFloat(direction*12);
      jQuery("#"+this.config.calendarStage+"_year").html(this.getYearPage());
      this.gotoYearEnd();
    }else{
      this.gotoYear();
    }
  },
  onClick: function(event){
    if(event.target.tagName == "A"){
      var el =  event.target.id;
      var ids = el.split("_");
      var l = ids.length-1;
      var m = l-1;
      var seq = ids[l];
      if(ids[m] == "y"){
        this.yearActive(false);
        this.config.nowYear = parseFloat(seq);
        this.gotoMonth();
      }else if(ids[m] == "m"){
        this.monthActive(false);
        this.config.now = new Date(this.config.nowYear, (seq-1), 1);
        this.config.bef = this.config.now.add(-1, "m");
        this.config.aft = this.config.now.add(1, "m");
        this.initMonth();
        this.gotoDay();
      }else{
        if(this.config.onSelectDay) this.config.onSelectDay(seq.date());
        this.setDate(seq.date());
      }
    }
  },
  getStat : function(){
    return this.panelStat;
  },
  getDate: function(){
    return this.config.now;
  }
});

var modsDate = Class.create(modsAX, {
  version       : "modsDate V1.0",
  author        : "SQUALL",
  createDate    : "2010.04.26",
  lastModifyDate: "2010.04.26",
  initialize: function($super){
    $super();

    this.active = false;
    this.positioning = false; // if you need repositioning then this.positioning = false;
    this.coverA = "href=\"#modsExceptionScript\"";

    with(this){
      config.allowYears = [1000, 3000];
      config.containerClassName = "modsDate";
      config.calendarClassName = "modsDatePanel";
      config.calendarControlBox = "modsDatePanelControl";
      config.calendarControlprev = "mdp_prev";
      config.calendarControlnext = "mdp_next";
      config.calendarControltitle = "mdp_title";
      config.containerMargin = {left:0, top:10};
      config.arrow = true;
      config.zindex = 100;
      config.easing = {
        open:{duration:300, easing:"swing"},
        close:{duration:300, easing:"swing"}
      };
      config.inputErrorMsg = "날짜형식이 아닙니다.";
    }
  },
  /* ------------------------------------------------------------------------------------------------------------------ */
  /* init ~~~~~~ */
  init: function(){
    var onkeyup = this.onkeyup.bind(this);
    if(mods.browser.browser == "ie" && mods.browser.version == 6){
    jQuery("#"+this.config.inputID).bind("keyup", onkeyup);
    }else{
    jQuery("#"+this.config.inputID).bind("keydown", onkeyup);
    }

    jQuery("#"+this.config.inputID).bind("focus", function(){
      this.select(); 
    });
    jQuery("#"+this.config.inputID).bind("blur", this.onBlur.bind(this));
    this.initContainerPin();
    this.container = jQuery("<div class=\""+this.config.calendarClassName+"\" id=\""+this.config.inputID+"_container\"></div>");
    this.initCalendarControl();
    if(this.config.arrow) this.initArrow();
  },
  initCalendarControl: function(){
    //달력 컨트롤 구성
    var po = [];
    po.push("<div class=\""+this.config.calendarControlBox+"\">");
    po.push("<a class=\""+this.config.calendarControlprev+"\" href=\"#modsExectionScript\" id=\""+this.config.inputID+"_prev\">P</a>");
    po.push("<a class=\""+this.config.calendarControltitle+"\" id=\""+this.config.inputID+"_caltit\" href=\"#modsExectionScript\"></a>");
    po.push("<a class=\""+this.config.calendarControlnext+"\" href=\"#modsExectionScript\" id=\""+this.config.inputID+"_next\">N</a>");
    po.push("</div>");
    this.container.append(po.join(''));
    this.container.find("."+this.config.calendarControlBox).bind("click", this.controlClick.bind(this));
  },
  initContainerPin: function(){
    this.containerPin = jQuery("<div id=\""+this.config.inputID+"_containerPin\" class=\""+this.config.containerClassName+"\"></div>");
    var iobj = jQuery("#"+this.config.inputID);
    iobj.before(this.containerPin);

    var offSetParent = iobj.offsetParent();
    var bt = 0;
    var bl = 0;
    try{
      bt = offSetParent.css("border-top-width").number();
    }catch(e){}
    try{
      bl = offSetParent.css("border-left-width").number();
    }catch(e){}

    var offSet = iobj.position();
    var offBox = {width:iobj.outerWidth(), height:iobj.outerHeight(true)};

    var mybr = mods.browser.browser;
    var brver = mods.browser.version;

    if(mybr == "ie" && brver == 6){
      this.containerPin.css({"top":(offSet.top-bt)+"px"});
    }else if(mybr == "ie" && brver == 7){
      this.containerPin.css({"top":(offSet.top-bt+1)+"px"});
    }else{
      this.containerPin.css({left:(offSet.left)+"px", "top":(offSet.top)+"px"});
    }
    this.containerPin.css({"width":offBox.width+"px"});

    if(mybr == "moz"){
      this.containerPin.bind("keypress", this.onkeyup.bind(this));
    }else if(mybr == "wk"){
      this.containerPin.bind("keydown", this.onkeyup.bind(this));
    }else{
      this.containerPin.bind("keydown", this.onkeyup.bind(this));
    }

  },
  initArrow: function(){
    /* arrow positioning */
    this.arrow = jQuery("<a "+this.coverA+" id=\""+this.config.inputID+"_arrow\" class=\"inputArrow\">select</a>");
    this.containerPin.append(this.arrow);
    var iobj = jQuery("#"+this.config.inputID);

    var offBox = {width:iobj.outerWidth(true), height:iobj.outerHeight(true)};
    this.arrow.css({right:"0px", top:"0px", height:(offBox.height)+"px"});

    var activeContainer = this.activeContainer.bind(this);
    this.arrow.bind("click", activeContainer);
  },
  showError: function(msg){
    var errorMsg = jQuery("<div class=\"inputError\">"+msg+"</div>");
    this.containerPin.append(errorMsg);
    var iobj = jQuery("#"+this.config.inputID);
    var offBox = {width:iobj.outerWidth(true), height:iobj.outerHeight(true)};
    errorMsg.css({left:"0px", top:(offBox.height)+"px", width:(offBox.width)-2+"px", height:(offBox.height)+"px"});
    errorMsg.fadeIn().delay(500).fadeOut();
  },
  onkeyup: function(event){
    if(this.active){
      if(this.observer) clearTimeout(this.observer);
      if(event.keyCode == mods.Event.KEY_DOWN)  this.goDOWN();
      else if(event.keyCode == mods.Event.KEY_UP)    this.goUP();
      else if(event.keyCode == mods.Event.KEY_LEFT)  this.goLEFT();
      else if(event.keyCode == mods.Event.KEY_RIGHT) this.goRIGHT();
      else if(event.keyCode == mods.Event.KEY_HOME) this.goTAB();
      else if(event.keyCode == mods.Event.KEY_PAGEUP) this.goPrev();
      else if(event.keyCode == mods.Event.KEY_PAGEDOWN) this.goNext();
      else if(event.keyCode == mods.Event.KEY_ESC)   this.deActiveContainer();
      else if(event.keyCode == mods.Event.KEY_RETURN){
        jQuery("#"+this.config.inputID).val(this.calendar.getDate().say());
        this.deActiveContainer();
        event.stopPropagation();
        return;
      }
    }else{
      if(event.keyCode == mods.Event.KEY_DOWN)  this.chdDOWN();
      else if(event.keyCode == mods.Event.KEY_UP)    this.chdUP();
      else if(event.keyCode == mods.Event.KEY_LEFT)  this.chdLEFT();
      else if(event.keyCode == mods.Event.KEY_RIGHT) this.chdRIGHT();
      else if(event.keyCode == mods.Event.KEY_HOME)  this.chdHOME();
      else if(event.keyCode == mods.Event.KEY_END) this.chdEND();
      else if(event.keyCode == mods.Event.KEY_PAGEUP) this.chdPAGEUP();
      else if(event.keyCode == mods.Event.KEY_PAGEDOWN) this.chdPAGEDOWN();
      else if(event.keyCode == mods.Event.KEY_RETURN){
        if(this.observer) clearTimeout(this.observer);
        if(this.activeObserver) clearTimeout(this.activeObserver);
        var va = jQuery("#"+this.config.inputID).val().replace(/\D/gi, "");
        this.updateInput(va.left(8));
        if(event.target.id == this.config.inputID) this.activeContainerACT();
        event.stopPropagation();
        return;
      }

      var onUpdate = this.onUpdate.bind(this);
      this.observer = setTimeout(function(){
        onUpdate();
      }, 500);
    }
  },
  onUpdate: function(){
    var va = jQuery("#"+this.config.inputID).val().replace(/\D/gi, "");
    if(va.length > 7){
      this.updateInput(va.left(8));
    }
  },
  onBlur: function(){
    var va = jQuery("#"+this.config.inputID).val().replace(/\D/gi, "");
    if(va.search(/\d+/g) == -1){
      jQuery("#"+this.config.inputID).val("");
      return;
    }
    this.updateInput(va.left(8));
  },
  updateInput: function(va){
    if(va == "") return;
    var td = new Date();
    if(va.length == 8){
      var yy = va.left(4);
      var mm = va.right(4).left(2);
      var dd = va.right(2);
    }else if(va.length == 7){
      var yy = va.left(4);
      var mm = va.right(3).left(1);
      var dd = va.right(2);
    }else if(va.length == 6){
      var yy = va.left(4);
      var mm = va.right(2).left(1);
      var dd = va.right(1).pad(2);
    }else{
      var yy = va.left(4);
      var mm = 1;
      var dd = 1;
    }
    if(yy < this.config.allowYears[0] || yy > this.config.allowYears[1]) yy = td.getFullYear();
    if(mm > 12) mm = 12;
    if(mm == 0) mm = 1;
    var md = mods.monthLength(yy, (mm-1));
    if(dd > md) dd = md;
    if(dd == 0) dd = 1;
    jQuery("#"+this.config.inputID).val(yy+"-"+mm.pad(2)+"-"+dd.pad(2));
  },
  controlClick: function(event){
    if(event.target.tagName != "A") return;
    if(jQuery(event.target).hasClass(this.config.calendarControlprev)){
      this.goPrev();
    }else if(jQuery(event.target).hasClass(this.config.calendarControlnext)){
      this.goNext();
    }else if(jQuery(event.target).hasClass(this.config.calendarControltitle)){
      this.goTAB();
    }
  },
  goLEFT: function(){
    var cs = this.calendar.getStat();
    if(cs == 2) this.calendar.moveDay(-1);
    else if(cs == 1) this.calendar.moveMonth(-1);
    else if(cs == 0) this.calendar.moveYear(-1);
  },
  goRIGHT: function(){
    var cs = this.calendar.getStat();
    if(cs == 2) this.calendar.moveDay(1);
    else if(cs == 1) this.calendar.moveMonth(1);
    else if(cs == 0) this.calendar.moveYear(1);
  },
  goUP: function(){
    var cs = this.calendar.getStat();
    if(cs == 2) this.calendar.moveDay(-7);
    else if(cs == 1) this.calendar.moveMonth(-3);
    else if(cs == 0) this.calendar.moveYear(-3);
  },
  goPrev: function(){
    var cs = this.calendar.getStat();
    if(cs == 2) this.calendar.moveMonth(-1);
    else if(cs == 1) this.calendar.moveYear(-1);
    else if(cs == 0) this.calendar.movePage(-1);
  },
  goNext: function(){
    var cs = this.calendar.getStat();
    if(cs == 2) this.calendar.moveMonth(1);
    else if(cs == 1) this.calendar.moveYear(1);
    else if(cs == 0) this.calendar.movePage(1);
  },
  goDOWN: function(){
    var cs = this.calendar.getStat();
    if(cs == 2) this.calendar.moveDay(7);
    else if(cs == 1) this.calendar.moveMonth(3);
    else if(cs == 0) this.calendar.moveYear(3);
  },
  goTAB: function(){
    var cs = this.calendar.getStat();
    if(cs == 2) this.calendar.gotoMonth();
    else if(cs == 1) this.calendar.gotoYear();
    else if(cs == 0) this.calendar.gotoDay();
  },
  chdDOWN: function(){
    var va = jQuery("#"+this.config.inputID).val().replace(/\D/gi, "");
    this.updateInput(va.left(8));
    var md = jQuery("#"+this.config.inputID).val().date();
    jQuery("#"+this.config.inputID).val(md.add(1, "m").say());
  },
  chdUP: function(){
    var va = jQuery("#"+this.config.inputID).val().replace(/\D/gi, "");
    this.updateInput(va.left(8));
    var md = jQuery("#"+this.config.inputID).val().date();
    jQuery("#"+this.config.inputID).val(md.add(-1, "m").say());
  },
  chdLEFT: function(){
    var va = jQuery("#"+this.config.inputID).val().replace(/\D/gi, "");
    this.updateInput(va.left(8));
    var md = jQuery("#"+this.config.inputID).val().date();
    jQuery("#"+this.config.inputID).val(md.add(-1, "d").say());
  },
  chdRIGHT: function(){
    var va = jQuery("#"+this.config.inputID).val().replace(/\D/gi, "");
    this.updateInput(va.left(8));
    var md = jQuery("#"+this.config.inputID).val().date();
    jQuery("#"+this.config.inputID).val(md.add(1, "d").say());
  },
  chdHOME: function(){
    var va = jQuery("#"+this.config.inputID).val().replace(/\D/gi, "");
    this.updateInput(va.left(8));
    jQuery("#"+this.config.inputID).val(jQuery("#"+this.config.inputID).val().left(7)+"-01");
  },
  chdEND: function(){
    var va = jQuery("#"+this.config.inputID).val().replace(/\D/gi, "");
    this.updateInput(va.left(8));
    var md = jQuery("#"+this.config.inputID).val().date();
    jQuery("#"+this.config.inputID).val(md.say().left(7)+"-"+mods.monthLength(md.getFullYear(), md.getMonth()));
  },
  chdPAGEUP: function(){
    var va = jQuery("#"+this.config.inputID).val().replace(/\D/gi, "");
    this.updateInput(va.left(8));
    var md = jQuery("#"+this.config.inputID).val().date();
    jQuery("#"+this.config.inputID).val(md.add(1, "y").say());
  },
  chdPAGEDOWN: function(){
    var va = jQuery("#"+this.config.inputID).val().replace(/\D/gi, "");
    this.updateInput(va.left(8));
    var md = jQuery("#"+this.config.inputID).val().date();
    jQuery("#"+this.config.inputID).val(md.add(-1, "y").say());
  },
  activeContainer: function(){
    if(this.activeObserver) clearTimeout(this.activeObserver);
    if(this.active){
      this.deActiveContainer();
      return;
    }
    var onActive = this.activeContainerACT.bind(this);
    this.activeObserver = setTimeout(function(){
      onActive();
    }, 10);
  },
  activeContainerACT: function(){
    if(this.active) return;

    if(!this.calendar){
      this.containerPin.append(this.container);
      var onDisplay = this.calendarTitle.bind(this);
      var onselectDay = this.onselectDay.bind(this);
      this.calendar = new modsCalendar();
      this.calendar.setConfig({
        calendarStage:this.container[0].id,
        onDisplay: onDisplay,
        onSelectDay: onselectDay
      });
    }
    this.calendar.setDate(jQuery("#"+this.config.inputID).val().date());
    jQuery("#"+this.config.inputID).select();
    this.active = true;
    if(this.arrow) this.arrow.addClass("sted");
    this.otherClick = this.onOtherClick.bind(this);
    jQuery(document).bind("click", this.otherClick);
    this.containerPin.css({"zIndex":"99999"});
    if(!this.positioning) this.setPosition();
    this.container.css({"display":"none"});
    this.container.fadeIn({duration:this.config.easing.open.duration, easing:this.config.easing.open.easing});
  },
  onOtherClick: function(event){
    var eA = event.target;
    if(eA.id.search(this.config.inputID) == -1) this.deActiveContainer();
  },
  deActiveContainer: function(){
    this.active = false;
    this.container.fadeOut({duration:this.config.easing.close.duration, easing:this.config.easing.close.easing});
    if(this.arrow) this.arrow.removeClass("sted");
    jQuery(document).unbind("click", this.otherClick);
  },
  calendarTitle: function(str){
    jQuery("#"+this.config.inputID+"_caltit").html(str);
  },
  onselectDay: function(day){
    jQuery("#"+this.config.inputID).val(day.say());
    this.deActiveContainer();
    if(this.config.onSelectDay) this.config.onSelectDay(day.say());
  },
  setPosition: function(){
    var iobj = jQuery("#"+this.config.inputID);
    var offSet = iobj.position();
    var offBox = {width:iobj.outerWidth(true), height:iobj.outerHeight(true)};
    var ctBox = {width:this.container.outerWidth(true), height:this.container.outerHeight(true)};

    var l = offBox.width/2 - ctBox.width/2;
    var t = offBox.height/2 - ctBox.height/2;

    this.container.css({top:t+this.config.containerMargin.top, left:l+this.config.containerMargin.left});
    this.positioning = true;
  }
})